「哇,原來研究室是這樣的啊。」詩憶東張西望。
「是呀,這裡是大家辦公的地方,實驗的機器不在這裡,所以妳可以放心坐下來。」唯心拉開身邊的椅子,回頭繼續寫報告。
詩憶下午的時間有空堂,想要找個安靜的地方自習,但系計中(系上的計算機中心,提供多台公共電腦和舒適的冷氣)和圖書館都人滿為患,回寢室又太遠。於是傳訊息問學姐還有沒有適合的地方,沒想到學姐回答可以去她的研究室。
詩憶坐下後,拿出筆電開始研究講義上的Nullable
範例,她在宣告變數的類別後面加上問號。
fun main() {
var drink : Drink?
println(drink)
}
IDE馬上吐出紅字錯誤Variable 'drink' must be initialized
。
「妳忘記初始化了。」唯心幾乎是和IDE同時反應。
「喔,學姐妳有在看啊。」詩憶害羞地用手指搔搔臉。「我可以順便問問這個字怎麼發音嗎?」
「null
在台灣還滿盛行唸成『怒喔』,但如果要和英美人士交流的話,音標是『nʌl』,發音接近NO。基本上溝通就是要讓對方聽懂,所以建議兩種念法都記下來。null
是一個特殊的值,當變數被設定成null
這個空虛值,就代表這個變數失去原類別的所有能力,只剩下Any
支援的函式,被扔在記憶體hashCode
為0的位置,所有的null
變數都是被扔在那,所以通常是拿來解放原本佔據的記憶體的。所以?.
後面的函式和屬性只在變數非null
的時候才會去呼叫。」唯心一邊幫她修正程式一邊說。
fun main() {
var drink : Drink? = null
println(drink)
println(drink?.name)
}
IDE這次沒有紅字,印出兩行null
。
「不能延後初始化嗎?」詩憶問。
唯心注意到螢幕的髒污,拿出拭鏡布擦乾淨了才回答。
「可以,不過val
和var
延後初始化的方法不同唷,var
是在前面加上lateinit
,val
是在後面加上by lazy
。意義上不太一樣,lateinit
是希望開發者能自發在用到這個變數前初始化,如果在用到變數時還是沒有初始化的話就會拋出UninitializedPropertyAccessException
錯誤;而by lazy
則事先準備好初始化的方法,程式會在用到變數的前一刻才初始化。」
fun main() {
lateinit var drink : Drink
drink = Drink("奶茶", 50)
println(drink)
}
fun main() {
val drink : Drink by lazy {
println("initial")
Drink("奶茶", 50)//初始化的部分要放在lazy裡的最後一行唷
}
println(drink)
}
「之前練習四則運算的時候就想問,Exception
到底是什麼啊?」
唯心乾脆蓋上筆電,專心回答詩憶。
「throw Exception
歸屬於Nothing
類別,是一種中斷程式、放置安全閘的手段,比如說,程式還沒設計完的時候通常會放個TODO
,如果有誰不小心呼叫了這個未完成的地方,就會收到錯誤。之前的四則運算則是擋住不支援的字元符號,而有些Exception
是系統拋出的,可以的話盡量不要踩到那些坑,像是很有名的NPE
指的就是NullPointerException
,當程式企圖操作已經null
化的變數就會引爆。因為Kotlin有預先檢查,相對於同生態系的Java程式語言來說Null Safety
程度比較高,但是也因為同生態系內的程式語言可以互相使用對方的函式庫,所以還是有可能踩到對方的坑。不過,也不能說Kotlin自己就不會發生NullPointerException
,如果刻意呼叫throw NullPointerException
或是使用!!
無視null
狀態,會爆炸的還是會爆炸。」
fun 飲料優惠活動() {
TODO("總有一天要完成")
}
fun notSupport(char: Char): Nothing {
throw IllegalArgumentException("Not Support ${char}!")
}
fun main() {
var drink : Drink? = null
println(drink)
println(drink!!.name)//會爆炸
}
「遇到Exception
只能爆炸嗎?不會吧?」詩憶懷疑。
唯心點頭。「如妳猜測的,對於在預期中可以包容的Exception
,能用try-catch
包起來不讓它爆炸。」
fun main() {
try {
notSupport('#')
} catch (e: IllegalArgumentException) {
println(e.message)
}
}
程式順利執行,印出一般顏色的Not Support #!
。